<?php

namespace App\Library\Service;

use App\Library\Logic\BuyWillLogic;
use App\Library\Logic\KefuLogic;
use App\Library\Logic\OpenIdLogic;
use App\Library\Logic\OperateLogLogic;
use App\Library\Logic\ShopProductLogic;
use App\Library\Logic\ProductSpecLogic;
use App\Library\Logic\ShopProductSpecsLogic;
use App\Library\Logic\ShopUserCollectLogic;
use App\Library\Logic\ShopUserLogic;
use App\Library\Requests\Base\BasePageRequest;
use App\Library\Requests\Base\IdRequest;
use App\Library\Requests\Base\SerialNumberRequest;
use App\Library\Requests\Product\DayTjRequest;
use App\Library\Requests\Product\ProductCustomerServicePagingRequest;
use App\Library\Requests\Product\ProductPageRequest;
use App\Library\Requests\Product\ProductStatusRequest;
use App\Library\Requests\Product\ProductUserPageRequest;
use App\Library\Requests\Product\TjRequest;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;

class ShopProductService extends BaseService
{
    /**
     * logic
     * @return ShopProductLogic
     */
    private function logic(): ShopProductLogic
    {
        if (empty($this->logic)) $this->logic = new ShopProductLogic;
        return $this->logic;
    }

    public function tj(TjRequest $request): JsonResponse
    {
        $user = ShopUserLogic::query()->where('user_id', USERID)->first();
        if (is_null($user)) return fail(433);
        return success($this->logic()->tj($request, $user));
    }

    /**
     * 产品日统计
     * @param DayTjRequest $request
     * @return JsonResponse
     *
     */
    public function dayTj(DayTjRequest $request): JsonResponse
    {
        if ($request->type !== 3) $result = $this->logic()->dayTj($request);
        else $result = BuyWillLogic::dayTj($request);
        return success($result);
    }

    /**
     * 分页
     * @param ProductPageRequest $request
     * @return JsonResponse
     *
     */
    public function paging(ProductPageRequest $request): JsonResponse
    {
        if ($request->status !== 3) $result = self::commonPage($this->logic()->paging($request), 1);
        else $result = BuyWillLogic::paging($request);
        return success($result);
    }

    /**
     * 用户产品列表
     * @param ProductUserPageRequest $request
     * @return JsonResponse
     *
     */
    public function userPaging(ProductUserPageRequest $request): JsonResponse
    {
        if ($request->isAgent === true && !cache()->has('agent:' . userId())) return fail(422);
        else return success(self::commonPage($this->logic()->userPaging($request)));
    }

    public function commonPage($data, int $type = 0)
    {
        foreach ($data['data'] as &$value) {
            $value->product_special_start_time = $value->product_special_start_time > 0 ? date('Y-m-d H:i:s', $value->product_special_start_time) : 0;
            $value->product_special_end_time = $value->product_special_end_time > 0 ? date('Y-m-d H:i:s', $value->product_special_end_time) : 0;
            $specs = ProductSpecLogic::getSpecsCommissionInfo($value->product_id);

            if (!empty($specs)) {
                $psPrice = array_filter(array_column($specs, 'ps_price'), function ($v) {
                    return $v > 0;
                });
                $underlinePrice = array_filter(array_column($specs, 'ps_price_underlined'), function ($v) {
                    return $v > 0;
                });
                $commission = self::commonCommission([
                    'start_time' => $value->product_special_start_time,
                    'end_time' => $value->product_special_end_time,
                    'specs' => $specs
                ]);
                $value->lower_commission = $commission['lower_commission'];

                if ($type) {
                    $value->discount_price = empty($psPrice) || min($psPrice) >= min($underlinePrice) ? min($underlinePrice) : min($psPrice);
                    $value->normal_price = min($underlinePrice) === max($underlinePrice) ? min($underlinePrice) : min($underlinePrice) . '~' . max($underlinePrice);
                } else {
                    $value->normal_price = $commission['normal_price'];
                    $value->discount_price = empty($psPrice) || min($psPrice) >= min($underlinePrice) ? min($underlinePrice) : min($psPrice);
                }
            } else {
                $value->discount_price = 0;
                $value->normal_price = 0;
            }
            $value->discount_price = (float)$value->discount_price;
            $value->normal_price = (float)$value->normal_price;
        }

        return $data;
    }

    public static function commonGoodsPage($data, int $type = 0)
    {
        foreach ($data['data'] as &$value) {
            $value->product_special_start_time = $value->product_special_start_time > 0 ? date('Y-m-d H:i:s', $value->product_special_start_time) : 0;
            $value->product_special_end_time = $value->product_special_end_time > 0 ? date('Y-m-d H:i:s', $value->product_special_end_time) : 0;
            $specs = ProductSpecLogic::getSpecsCommissionInfo($value->product_id);

            if (!empty($specs)) {
                $psPrice = array_filter(array_column($specs, 'ps_price'), function ($v) {
                    return $v > 0;
                });
                $underlinePrice = array_filter(array_column($specs, 'ps_price_underlined'), function ($v) {
                    return $v > 0;
                });
                $commission = self::commonGoodCommission([
                    'start_time' => $value->product_special_start_time,
                    'end_time' => $value->product_special_end_time,
                    'specs' => $specs
                ]);
                $value->lower_commission = $commission['lower_commission'];

                if ($type) {
                    $value->discount_price = empty($psPrice) || min($psPrice) >= min($underlinePrice) ? min($underlinePrice) : min($psPrice);
                    $value->normal_price = min($underlinePrice) === max($underlinePrice) ? min($underlinePrice) : min($underlinePrice) . '~' . max($underlinePrice);
                } else {
                    $value->normal_price = $commission['normal_price'];
                    $value->discount_price = empty($psPrice) || min($psPrice) >= min($underlinePrice) ? min($underlinePrice) : min($psPrice);
                }
            } else {
                $value->discount_price = 0;
                $value->normal_price = 0;
            }
            $value->discount_price = (float)$value->discount_price;
            $value->normal_price = (float)$value->normal_price;
        }

        return $data;
    }

    /**
     * 热卖
     * @param BasePageRequest $request
     * @return JsonResponse
     */
    public function recommendList(BasePageRequest $request): JsonResponse
    {
        return success(self::commonPage($this->logic()->recommendList($request)));
    }

    public function specialOffer(IdRequest $request): JsonResponse
    {
        $model = ShopProductLogic::findByWhere(['productId' => $request->id]);
        if (is_null($model)) return fail(433);
        if ($model->product_special_start_time <= time() && $model->product_special_end_time > time()) return success(['is_special_price' => true]);
        else return success(['is_special_price' => false]);
    }

    /**
     * 详情
     * @param IdRequest $request
     * @return JsonResponse
     *
     */
    public function detail(IdRequest $request): JsonResponse
    {
        $model = ShopProductLogic::detail($request->id);
        if (is_null($model)) return fail(433);
        $userId = userId();
        if ($model->is_agent && !cache()->has('agent:' . $userId)) return fail(422);
        $specs = ProductSpecLogic::getSpecsCommissionInfo($model->product_id);
        $commission = self::commonCommission([
            'start_time' => date('Y-m-d H:i:s', $model->product_special_start_time),
            'end_time' => date('Y-m-d H:i:s', $model->product_special_end_time),
            'specs' => $specs
        ]);
        //添加点击
        $model->product_hits += 1;
        $model->save();
        $model->lower_commission = $commission['lower_commission'];
        $model->normal_price = $commission['normal_price'];
        $model->specs;
        $model->collect = ShopUserCollectLogic::existsByWhere([
            'ucType' => 1,
            'userId' => $userId,
            'ucSourceId' => $model->product_id
        ]);
        $model->isFollow = OpenIdLogic::existsByWhere([
            'userId' => $userId,
            'plateform' => 2,
            'type' => 'wx',
            'isFollow' => 1
        ]);
        $model->is_kefu = $userId > 0 && $model->user_id === KefuLogic::isKeFu($userId);
        if ($model->plug2 === 1) {
            $model->second = $this->logic()->reduce($model->product_special_start_time, $model->ext->plug_hour);
            unsetObject($model, ['ext']);
        }
        return success($model);
    }

    private function commonCommission(array $data): array
    {
        //佣金
        $commissionArr = array_filter(array_column($data['specs'], 'commission'), function ($v) {
            return $v > 0;
        });
        //优惠价*比例后的佣金
        $commissionRatioArr = array_filter(array_column($data['specs'], 'commission_ratio'), function ($v) {
            return $v > 0;
        });
        //原价*比例后的佣金
        $underlineCommissionRatioArr = array_filter(array_column($data['specs'], 'underline_commission_ratio'), function ($v) {
            return $v > 0;
        });

        $now = now()->toDateTimeString();
        if ($data['start_time'] <= $now && $data['end_time'] > $now) {
            if (empty($commissionArr) && empty($commissionRatioArr)) $arr['lower_commission'] = 0;
            else if (!empty($commissionArr) && empty($commissionRatioArr)) $arr['lower_commission'] = min($commissionArr);
            else if (empty($commissionArr) && !empty($commissionRatioArr)) $arr['lower_commission'] = min($commissionRatioArr);
            else $arr['lower_commission'] = min($commissionArr) <= min($commissionRatioArr) ? min($commissionArr) : min($commissionRatioArr);

            usort($data['specs'], function ($a, $b) {
                if ($a['ps_price'] == $b['ps_price']) {
                    return 0;
                }
                return ($a['ps_price'] < $b['ps_price']) ? -1 : 1;
            });
        } else {
            if (empty($commissionArr) && empty($underlineCommissionRatioArr)) $arr['lower_commission'] = 0;
            else if (!empty($commissionArr) && empty($underlineCommissionRatioArr)) $arr['lower_commission'] = min($commissionArr);
            else if (empty($commissionArr) && !empty($underlineCommissionRatioArr)) $arr['lower_commission'] = min($underlineCommissionRatioArr);
            else $arr['lower_commission'] = min($commissionArr) <= min($underlineCommissionRatioArr) ? min($commissionArr) : min($underlineCommissionRatioArr);
            usort($data['specs'], function ($a, $b) {
                if ($a['ps_price_underlined'] == $b['ps_price_underlined']) {
                    return 0;
                }
                return ($a['ps_price_underlined'] < $b['ps_price_underlined']) ? -1 : 1;
            });
        }
        $arr['normal_price'] = $data['specs'][0]['ps_price_underlined'] ?? null;
        $arr['normal_price'] = (float)$arr['normal_price'];
        return $arr;
    }

    public static function commonGoodCommission(array $data): array
    {
        //佣金
        $commissionArr = array_filter(array_column($data['specs'], 'commission'), function ($v) {
            return $v > 0;
        });
        //优惠价*比例后的佣金
        $commissionRatioArr = array_filter(array_column($data['specs'], 'commission_ratio'), function ($v) {
            return $v > 0;
        });
        //原价*比例后的佣金
        $underlineCommissionRatioArr = array_filter(array_column($data['specs'], 'underline_commission_ratio'), function ($v) {
            return $v > 0;
        });

        $now = now()->toDateTimeString();
        if ($data['start_time'] <= $now && $data['end_time'] > $now) {
            if (empty($commissionArr) && empty($commissionRatioArr)) $arr['lower_commission'] = 0;
            else if (!empty($commissionArr) && empty($commissionRatioArr)) $arr['lower_commission'] = min($commissionArr);
            else if (empty($commissionArr) && !empty($commissionRatioArr)) $arr['lower_commission'] = min($commissionRatioArr);
            else $arr['lower_commission'] = min($commissionArr) <= min($commissionRatioArr) ? min($commissionArr) : min($commissionRatioArr);

            usort($data['specs'], function ($a, $b) {
                if ($a['ps_price'] == $b['ps_price']) {
                    return 0;
                }
                return ($a['ps_price'] < $b['ps_price']) ? -1 : 1;
            });
        } else {
            if (empty($commissionArr) && empty($underlineCommissionRatioArr)) $arr['lower_commission'] = 0;
            else if (!empty($commissionArr) && empty($underlineCommissionRatioArr)) $arr['lower_commission'] = min($commissionArr);
            else if (empty($commissionArr) && !empty($underlineCommissionRatioArr)) $arr['lower_commission'] = min($underlineCommissionRatioArr);
            else $arr['lower_commission'] = min($commissionArr) <= min($underlineCommissionRatioArr) ? min($commissionArr) : min($underlineCommissionRatioArr);
            usort($data['specs'], function ($a, $b) {
                if ($a['ps_price_underlined'] == $b['ps_price_underlined']) {
                    return 0;
                }
                return ($a['ps_price_underlined'] < $b['ps_price_underlined']) ? -1 : 1;
            });
        }
        $arr['normal_price'] = $data['specs'][0]['ps_price_underlined'] ?? null;
        $arr['normal_price'] = (float)$arr['normal_price'];

        return $arr;
    }
    /**
     * 商品发布和取消
     * @param ProductStatusRequest $request
     * @return JsonResponse
     */
    public function transStatus(ProductStatusRequest $request): JsonResponse
    {
        if (empty($request->serialNumberArr)) {
            $model = $this->logic()->findBySerialNumber($request);
            if (is_null($model)) return fail(433);
            else if ($model->product_status === 2) {
                $model->product_status = 1;
                $model->product_offline_time = now()->timestamp;
            } else {
                if (!ShopProductSpecsLogic::existsByWhere(['productId' => $model->product_id, 'psIsDelete' => 2])) {
                    return failMessage('无规格商品不可发布');
                }
                $model->product_status = 2;
                $model->product_online_time = now()->timestamp;
                $model->publish_at = now();
                $model->operated_at = now();
            }
            $model->save();
        } else {
            foreach ($request->serialNumberArr as $val) {
                $model = $this->logic()->findByWhere(['serialNumber' => $val]);
                if (is_null($model)) return fail(433);
            }

            $this->logic()->query()->whereIn('serial_number', $request->serialNumberArr)->update([
                'product_status' => $request->productStatus,
                'operated_at' => now(),
            ]);
        }
        OperateLogLogic::add();
        return success();
    }

    public function customerServicePaging(ProductCustomerServicePagingRequest $request): JsonResponse
    {
        return success(self::commonPage($this->logic()->customerServicePaging($request)));
    }

    /**
     *
     * @param SerialNumberRequest $request
     * @return JsonResponse
     *
     */
    public function checkStock(SerialNumberRequest $request): JsonResponse
    {
        return success(
            $this->logic()->valueByWhere('serialNumber', $request->serialNumber, 'product_stock_empty')
        );
    }
}
